#pragma once

#include <AVUIMarkupExtension.h>

namespace AVUI {

/// <summary>Implements a markup extension that supports the binding between the value of a property in a template and the value of some other exposed property on the templated control.</summary>
class TemplateBindingExtension : public MarkupExtension
{
public:
    DECLARE_ELEMENT(TemplateBindingExtension, MarkupExtension);

#pragma region Public Methods

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.TemplateBindingExtension" /> class.</summary>
    TemplateBindingExtension() : m_pProperty(NULL) { };

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.TemplateBindingExtension" /> class with the specified dependency property that is the source of the binding.</summary>
    /// <param name="property">The identifier of the property being bound.</param>
    TemplateBindingExtension(DependencyProperty* pProperty);

    /// <summary>Returns an object that should be set as the value on the target object's property for this markup extension. For <see cref="T:System.Windows.TemplateBindingExtension" />, this is an expression (<see cref="T:System.Windows.TemplateBindingExpression" />) that supports the binding. </summary>
    /// <returns>The expression that supports the binding.</returns>
    /// <param name="serviceProvider">An object that can provide services for the markup extension. May be null in this implementation.</param>
    virtual TRefCountedPtr<Object> ProvideValue(IServiceProvider* pServiceProvider) AVUI_OVERRIDE;

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary>Gets or sets the converter that interprets between source and target of a binding.</summary>
    /// <returns>The converter implementation. This value defaults to null and is typically provided as an optional parameter of the binding.</returns>
    Object* get_Converter() { return m_pConverter; }
    void set_Converter(Object* pValue);

    /// <summary>Gets or sets the parameter to pass to the converter.</summary>
    /// <returns>The parameter being bound as referenced by the converter implementation. The default value is null.</returns>
    Object* get_ConverterParameter() { return m_pParameter; }
    void set_ConverterParameter(Object* pValue);

    DependencyProperty* get_Property() { return m_pProperty; }
    void set_Property(DependencyProperty* pValue);

#pragma endregion Public Properties

private:

#pragma region Private Fields

    TRefCountedPtr<Object> m_pConverter;
    TRefCountedPtr<Object> m_pParameter;
    DependencyProperty* m_pProperty;

#pragma endregion Private Fields

};

}; // namespace AVUI

